package api

import (
	"crypto/sha256"
	"encoding/hex"
	"game-handker/api/dbinit"
	"game-handker/pkg/jwt"
	"game-handker/restapi"
	"net/http"

	"github.com/gin-gonic/gin"
)

// 定义用户模型
type User struct {
	ID          uint   `gorm:"primaryKey;autoIncrement" json:"id"`
	Username    string `gorm:"uniqueIndex;notNull" json:"username"`
	Password    string `gorm:"notNull" json:"password"`
	PhoneNumber string `gorm:"notNull" json:"phoneNumber"`
	Email       string `json:"email"`
}

func (User) TableName() string {
	return "users_info"
}

/*
*
初始化连接Postgresql
*/
func init() {
	dbinit.Init()
	dbinit.DB.AutoMigrate(&User{})
}

// 注册接口
func Register() gin.HandlerFunc {
	return func(c *gin.Context) {
		var user User
		if err := c.ShouldBindJSON(&user); err != nil {
			restapi.FailResponse(c, err.Error(), http.StatusBadRequest)
			return
		}

		var existingUser User
		if err := dbinit.DB.Where("username = ?", user.Username).First(&existingUser).Error; err == nil {
			restapi.FailResponse(c, "用户名已存在", http.StatusConflict)
		} else {
			hash := sha256.New()
			hash.Write([]byte(user.Password))
			user.Password = hex.EncodeToString(hash.Sum(nil))
			dbinit.DB.Create(&user)
			token, err := jwt.GenerateToken(user.Username)
			if err != nil {
				restapi.FailResponse(c, "failed to generate token", http.StatusInternalServerError)
				return
			}
			restapi.OkResponse(c, gin.H{"data": gin.H{"token": token}})
		}
	}
}

// 登录接口
func Login() gin.HandlerFunc {
	return func(c *gin.Context) {
		var user User
		if err := c.ShouldBindJSON(&user); err != nil {
			restapi.FailResponse(c, err.Error(), http.StatusBadRequest)
			return
		}
		var storedUser User
		if err := dbinit.DB.Where("username = ?", user.Username).First(&storedUser).Error; err != nil {
			restapi.FailResponse(c, "用户不存在", http.StatusUnauthorized)
			return
		}
		hash := sha256.New()
		hash.Write([]byte(user.Password))
		if hex.EncodeToString(hash.Sum(nil)) != storedUser.Password {
			restapi.FailResponse(c, "用户名或密码错误", http.StatusUnauthorized)
			return
		}
		token, err := jwt.GenerateToken(user.Username)
		if err != nil {
			restapi.FailResponse(c, "failed to generate token", http.StatusInternalServerError)
			return
		}
		restapi.OkResponse(c, gin.H{"token": token})
	}
}
